package controllers

import (
	"NewEdu/models"
	"NewEdu/utils"
	"encoding/json"
	"fmt"
	"net/http"
	"sync"

	beego "github.com/beego/beego/v2/server/web"
	"github.com/gorilla/websocket"
)

// RecordsController operations for Classmates
type RecordsController struct {
	beego.Controller
}

func (c *RecordsController) Records() {
	c.TplName = "records.html"
}

func (c *RecordsController) Fill() {
	c.TplName = "fill.html"
}

func (c *RecordsController) Choujiang() {
	c.TplName = "choujiang.html"
}

var (
	choujiangChan = make(chan string, 500)
	choujiangMap  = make(map[string]string)
	mapMutex      = sync.RWMutex{}
	clients       = make(map[*websocket.Conn]bool)
	clientsMutex  = sync.RWMutex{}
)

// GetAll ...
// @Title 参与抽奖
// @Description 参与抽奖
// @Success 200 {object} models.Classmates
// @Failure 403
// @router /canyuChoujiang [get]
func (c *RecordsController) CanyuChoujiang() {
	user, err := utils.GetCurrentUser(c.Ctx)
	if err != nil {
		c.Data["json"] = utils.Export(utils.CodeUnauthorized, "获取用户失败", "请检查学号是否登记")
		c.ServeJSON()
		return
	}

	// 添加用户到地图中
	mapMutex.Lock()
	choujiangMap[user.SN] = user.Name
	mapMutex.Unlock()

	// 通知所有客户端有新用户加入
	choujiangChan <- user.SN

	result := make(map[string]interface{})
	result["sn"] = user.SN
	result["name"] = user.Name

	c.Data["json"] = utils.Export(utils.CodeSuccess, "参与抽奖成功", result)
	c.ServeJSON()
}

var upgrader = websocket.Upgrader{
	// 允许跨域请求，这里只是示例，实际生产环境需谨慎设置
	CheckOrigin: func(r *http.Request) bool {
		return true
	},
}

// LoadPersons ...
// @Title 载入抽奖人
// @Description 载入抽奖人
// @Success 200 {object} models.Classmates
// @Failure 403
// @router /loadPersons [get]
func (c *RecordsController) LoadPersons() {
	w := c.Ctx.ResponseWriter.ResponseWriter
	conn, err := upgrader.Upgrade(w, c.Ctx.Request, nil)
	if err != nil {
		result := utils.Export(utils.CodeInternalError, "WebSocket升级失败", err.Error())
		resultBytes, _ := json.Marshal(result)
		http.Error(w, string(resultBytes), http.StatusInternalServerError)
		return
	}
	defer conn.Close()

	// 添加客户端到客户端列表
	clientsMutex.Lock()
	clients[conn] = true
	clientsMutex.Unlock()
	defer func() {
		// 移除客户端
		clientsMutex.Lock()
		delete(clients, conn)
		clientsMutex.Unlock()
	}()

	// 发送空消息表示连接成功
	conn.WriteMessage(websocket.TextMessage, []byte(""))

	// 发送当前所有抽奖人信息
	mapMutex.RLock()
	for sn, name := range choujiangMap {
		err = conn.WriteMessage(websocket.TextMessage, []byte(name+"<br>"+sn))
		if err != nil {
			// 连接可能已关闭，记录日志但不返回错误
			fmt.Printf("WebSocket发送消息失败: %v\n", err)
			return
		}
	}
	mapMutex.RUnlock()

	// 持续监听新的抽奖参与者
	for {
		select {
		case sn := <-choujiangChan:
			person, err := models.GetTUserById(sn)
			if err != nil {
				// 如果获取用户失败，使用choujiangMap中的信息
				mapMutex.RLock()
				name, exists := choujiangMap[sn]
				mapMutex.RUnlock()
				
				if exists {
					// 广播给所有连接的客户端
					broadcastMessage([]byte(name+"<br>"+sn))
				}
			} else {
				// 更新地图中的信息
				mapMutex.Lock()
				choujiangMap[person.Sn] = person.Name
				mapMutex.Unlock()
				
				// 广播给所有连接的客户端
				broadcastMessage([]byte(person.Name+"<br>"+person.Sn))
			}
		}
	}
}

// 向所有客户端广播消息
func broadcastMessage(message []byte) {
	clientsMutex.RLock()
	defer clientsMutex.RUnlock()

	for client := range clients {
		err := client.WriteMessage(websocket.TextMessage, message)
		if err != nil {
			fmt.Printf("WebSocket发送消息失败: %v\n", err)
		}
	}
}

// ClearChoujiang ...
// @Title clearChoujiang
// @Description 删除参与投票的人员
// @Success 200 {object} models.Classmates
// @Failure 403
// @router /clearChoujiang [get]
func (c *RecordsController) ClearChoujiang() {
	mapMutex.Lock()
	choujiangMap = make(map[string]string)
	mapMutex.Unlock()
	
	c.Data["json"] = utils.Export(utils.CodeSuccess, "清空成功", choujiangMap)
	c.ServeJSON()
}
